\documentclass[11pt,a4paper]{article}

\setlength{\unitlength}{2em} % for the picture environment

\setlength{\parindent}{0pt}
\setlength{\parskip}{2ex}
\addtolength{\topmargin}{-1cm}
\addtolength{\textheight}{2cm}
\addtolength{\evensidemargin}{-1cm}
\addtolength{\oddsidemargin}{-1cm}
\addtolength{\textwidth}{2cm}

%\usepackage{syntonly}
%\usepackage[T1]{fontenc}
%\syntaxonly
%\author{Kong}
\title{Detailed Design Specification}
\date{}
\pagestyle{headings}
\begin{document}
% generates the title
\maketitle
\begin{flushright}
\begin{tabular}{|l|l|}
\hline
Project Title & kh-shell\\
\hline
Team Title & One-Man\\
\hline
Group Members & Kong\\
\hline
Document Version & 1.0.0\\
\hline
%Date & \date{}\\
Date & 2009.06.06\\
\hline
\end{tabular}
\end{flushright}
\begin{verbatim}


\end{verbatim}

\flushleft
\begin{enumerate}
\item \large \textbf{Scope}
\normalsize

We need a lightweight and a little powerful shell.\\
This document aimed to give both architectural-component level and data architecture level designs.

\item \large \textbf{Intened Audience}
\normalsize

This document is meant for developers, project managers, testers, and documentation writers.

\item \large \textbf{Architectural and Component-Level Design}
\normalsize

\begin{itemize}
\item \textbf{Architecture diagram}\\

\scriptsize
\setlength{\unitlength}{1.8em}
\begin{picture}(23.000000,23.000000)(-4.000000,-23.000000)
% picture environment flowchart generated by flow 0.99f
% Architecture diagram
\put(2.0000,-1.0000){\oval(4.0000,2.0000)}
\put(0.0000,-2.0000){\makebox(4.0000,2.0000)[c]{\shortstack[c]{
Begin
}}}
\put(2.0000,-2.0000){\vector(0,-1){1.0000}}
\put(0.0000,-5.0000){\framebox(4.0000,2.0000)[c]{\shortstack[c]{
Initialization\\
Module
}}}
\put(2.0000,-5.0000){\line(0,-1){1.0000}}
\put(2.0000,-6.0000){\vector(0,-1){1.0000}}
\put(-2.0000,-9.0000){\framebox(8.0000,2.0000)[c]{\shortstack[c]{
Get User Cmd From Stdin
}}}
\put(6.0000,-8.0000){\line(1,0){9.0000}}
\put(15.0000,-8.0000){\vector(0,-1){3.0000}}
\put(2.0000,-9.0000){\line(0,-1){1.0000}}
\put(2.0000,-10.0000){\vector(0,-1){1.0000}}
\put(-2.0000,-13.0000){\framebox(8.0000,2.0000)[c]{\shortstack[c]{
Syntax Analysis Module
}}}
\put(6.0000,-12.0000){\line(1,0){4.0000}}
\put(10.0000,-12.0000){\vector(1,0){1.0000}}
\put(11.0000,-13.0000){\framebox(8.0000,2.0000)[c]{\shortstack[c]{
Error Handling Module
}}}
\put(2.0000,-13.0000){\line(0,-1){1.0000}}
\put(2.0000,-14.0000){\vector(0,-1){1.0000}}
\put(-2.0000,-17.0000){\framebox(8.0000,2.0000)[c]{\shortstack[c]{
Executer Module 
}}}
\put(6.0000,-16.0000){\line(1,0){9.0000}}
\put(15.0000,-16.0000){\vector(0,1){3.0000}}
\put(2.0000,-17.0000){\line(0,-1){1.0000}}
\put(2.0000,-18.0000){\vector(0,-1){1.0000}}
\put(0.0000,-21.0000){\line(1,1){2.0000}}
\put(0.0000,-21.0000){\line(1,-1){2.0000}}
\put(4.0000,-21.0000){\line(-1,-1){2.0000}}
\put(4.0000,-21.0000){\line(-1,1){2.0000}}
\put(0.0000,-23.0000){\makebox(4.0000,4.0000)[c]{\shortstack[c]{
Exit?
}}}
\put(0.0000,-20.4000){\makebox(0,0)[rt]{N}}
\put(4.0000,-20.4000){\makebox(0,0)[lt]{Y}}
\put(4.0000,-21.0000){\line(1,0){2.0000}}
\put(6.0000,-21.0000){\vector(1,0){1.0000}}
\put(7.0000,-22.0000){\framebox(4.0000,2.0000)[c]{\shortstack[c]{
Release\\
Resource
}}}
\put(11.0000,-21.0000){\line(1,0){2.0000}}
\put(13.0000,-21.0000){\vector(1,0){1.0000}}
\put(16.0000,-21.0000){\oval(4.0000,2.0000)}
\put(14.0000,-22.0000){\makebox(4.0000,2.0000)[c]{\shortstack[c]{
Return
}}}
\put(0.0000,-21.0000){\line(-1,0){4.0000}}
\put(-4.0000,-21.0000){\line(0,1){13.0000}}
\put(-4.0000,-8.0000){\vector(1,0){2.0000}}
\end{picture}

\item \normalsize \textbf{Description of Components}\\

\begin{description}
\item[3.2.1] \textbf{Global Variables}\\

Global file gobal.h declares and defines variables and macros used by whole kh-shell project. Follows are the list of those ariables and macros.

\begin{verbatim}
err_no
Declare	   : extern int err_no;
Description: global error number stores the lastest error

1) reserved_words
Declare	   : extern char *reserved_words[];
Define	   : char *reserved_words[] = {
		"<",		//input redirection
		">",		//outputredirection
		"exit",		//exit the shell
		"&",		//running background
		"fg",		//running frontground
		"chgpmt",	//change prompt
		"cd",		//change work directory
	     };
Description: kh-shell reserved words

2) reserved_words_index
Declare	   : enum reserved_words_index{
		INPUT_REDIRECTION_INDEX,
		OUTPUT_REDIRECTION_INDEX,
		EXIT_INDEX,
		RUN_BCKGRND_INDEX,
		RUN_FRNTGRND_INDEX,
		CHGPRMT_INDEX,
		CD_INDEX
	     };
Description: kh-shell reserved words index

3) environ_argv
Declare	   : extern char *environ_argv[LAST_INDEX];
Description: environment variables

4) enum environ_argv_index
Declare	   : enum environ_argv_index{
		USER_INDEX	= 1, 	//login user name
		PWD_INDEX,		//present work directory
		HOME,			//home directory
		PROMPT_INDEX, 		//prompt
		LAST_INDEX, 		//last environment variable
	     };
Description: environment variables index

5) flags
Declare	   : extern int flags;
Description: a bit map to store reserved words set-up flags

6) macros to flag the bit value for echo reserved word int "flags"
Declare	   : 	//#define F_IFMASK		0x0000003F
		#define F_IFCD			0x00000080
		#define F_IFCHGPRMT		0x00000040
		#define F_IFFRNTGRND		0x00000020
		#define F_IFBCKGRND		0x00000010
		#define F_IFEXIT		0x00000008
		#define F_IFOPRE		0x00000004
		#define F_IFIPRE		0x00000002
		#define F_IFCMD			0x00000001
Description: the bit value for echo reserved word int "flags"

7) macros to get/set the set-up flag for echo reserved word int "flags"
Declare	   : 	#define SET_CD(flags) \
			flags = ((flags) | F_IFCD)
		#define IS_CD(flags) \
			(((flags) & F_IFCD) == F_IFCD
		#define SET_CMD(flags) \
			flags = ((flags) | F_IFCMD)
		#define IS_CMD(flags) \
			(((flags) & F_IFCMD) == F_IFCMD)
		#define SET_INPUT_REDIREC(flags) \
			flags = ((flags) | F_IFIPRE)
		#define IS_INPUT_REDIREC(flags) \
			(((flags) & F_IFIPRE) == F_IFIPRE)
		#define SET_OUTPUT_REDIREC(flags) \
			flags = ((flags) | F_IFOPRE)
		#define IS_OUTPUT_REDIREC(flags) \
			(((flags) & F_IFOPRE) == F_IFOPRE)
		#define SET_EXIT(flags) \
			flags = ((flags) | F_IFEXIT)
		#define IS_EXIT(flags) \
			(((flags) & F_IFEXIT) == F_IFEXIT)
		#define SET_RUN_BCKGRND(flags) \
			flags = ((flags) | F_IFBCKGRND)
		#define IS_RUN_BCKGRND(flags) \
			(((flags) & F_IFBCKGRND) == F_IFBCKGRND)
		#define SET_RUN_FRNTGRND(flags) \
			flags = ((flags) | F_IFFRNTGRND)
		#define IS_RUN_FRNTGRND(flags) \
			(((flags) & F_IFFRNTGRND) == F_IFFRNTGRND)
		#define SET_CHGPRMT(flags) \
			flags = ((flags) | F_IFCHGPRMT)
		#define IS_CHGPRMT(flags) \
			(((flags) & F_IFCHGPRMT) == F_IFCHGPRMT)
Description: get/set the set-up flag for echo reserved word int "flags"

\end{verbatim}

\item[3.2.2] \textbf{Environment Getting/Saving Module}\\

This module gets environment variable when shell starts and saves environment when shell quits. Except the loginning user name, all environmets are got from the config file .kh-shell which is a xml file stored at current user's home directory.\\
Libxml2 is the XML C parser and toolkit developed for the Gnome project, it is free software available under the MIT License. XML itself is a metalanguage to design markup languages, i.e. text language where semantic and structure are added to the content using extra "markup" information enclosed between angle brackets. Though the library is written in C a variety of language bindings make it available in other environments. Libxml2 is known to be very portable, the library should build and work without serious troubles on a variety of systems such ad Linux, Unix, Windows.\\
This module mainly incudes two external functions: get\_env\_info() and save\_env() and one internal fucntions: creat\_config\_file();\\

\begin{verbatim}
1) Interface of get_env_info():
Description : get environments from config file;
Declare     : int get_env_info(const char *filename, unsiged char **env);
Arguments   : filename: the config file name;
              env     : the array to get environments;
Return Value: 0, failed;
              0, successed;
Functions to Call: 
    xmlReadFile(): parse file from the filesystem or the network;
    xmlStrcmp(): compare node content;
    xmlNewTextChild(): create child node;
    xmlSaveFile(): save document tree to file;
    xmlFreeDoc(doc): free document tree;
    xmlCleanupParser() : free parser tree;

2) Interface of save_env():
Description : save environments to config file;
Declare     : int save_env(const char *filename, unsiged char **env);
Arguments   : filename: the config file name;
              env     : the array storing environments;
Return Value: 0, failed;
              0, successed;
Functions to Call: 
    creat_config_file(): create config file if it does not exists;
    access(filename, F_OK): determine whether the config file exits;
    xmlReadFile(): parse file from the filesystem or the network
    xmlStrcmp(): compare node content;
    xmlNewTextChild(): create child node;
    xmlSaveFile(): save document tree to file;
    xmlFreeDoc(doc): free document tree;
    xmlCleanupParser() : free parser tree;         

3) Interface of creat_config_file():
Description : create config file if it does not exists;
Declare     : int creat_config(const char *filename);
Arguments   : filename: the config file name;
Return Value: 0, failed;
              0, successed;
Functions to Call: 
    access(filename, F_OK): determine whether the config file exits;
    xmlReadFile(): parse file from the filesystem or the network
    xmlNewTextChild(): create child node;
    xmlSaveFile(): save document tree to file;
    xmlFreeDoc(doc): free document tree;
    xmlCleanupParser() : free parser tree;

\end{verbatim}

\item[3.2.3] \textbf{Syntax Paser Module}\\

This is one of the most important modules. It inlcudes laxical parser and syntax parser. The former labels token into cmds, arguments and reserved words. The later responses for setting syntex flags such as EXIT and putting them into the syntex tree. The syntex tree should containts at least cmd nodes, arguments nodes, input redirection file and output redirection file.
This module mainly incudes one external functions: syn\_analysis() and three internal fucntions: get\_first\_token(), get\_token(), is\_more\_token();\\

\begin{verbatim}
1) Interface of syn_analysis():
Description : get environments from config file;
Declare     : int get_env_info(const char *filename, unsiged char **env);
Arguments   : filename: the config file name;
              env     : the array to get environments;
Return Value: -1, failed;
              0, successed;
Functions to Call: 
    get_first_token(): get the first token in the input buffer;
    get_token(): get the next token in the input buffer;
    SET_XXX(): Macro, set flags;

2) Interface of get_first_token():
Description : get the first token in the input buffer;
Declare     : static char *get_first_token(char **buf);
Arguments   : buf: the input buffer;
Return Value: NULL, no token;
              A pointer to new alloc token, get the token;
Functions to Call: 
    calloc(): alloc new memory space for token;
    strncpy(): copy token to new space;        

3) Interface of get_token():
Description : get the next token in the input buffer;
Declare     : static char *get_token(char **buf);
Arguments   : buf: the input buffer;
Return Value: NULL, no token;
              A pointer to new alloc token, get the token;
Functions to Call: 
    calloc(): alloc new memory space for token;
    strncpy(): copy token to new space;     

4) Interface of is_more_token(():
Description : test whether there is more token in the input buffer;
Declare     : static char *get_first_token(char **buf);
Arguments   : buf: the input buffer;
Return Value: 0, no token;
              1, still having token;
Functions to Call: 

\end{verbatim}

\item[3.2.4] \textbf{Executer Module}\\

This module is divided into two parts, the first part deals with kh-shell reserved words and the second reposes for child process execution.\\
The first part deals with the reserved words: exit, chgpmt, fg and cd. By uses detecting macros, it can find whether those reserved words have been set up or not, and execute them for further.

\begin{verbatim}
Declare : void execute_cmd(char *cmd, char *arguments[], int flags);
Flow	:
{
//Part 1: deal with the reserved words

if (IS_EXIT(flags))
//code here
if (IS_CHGPRMT(flags))
//code here
if (IS_CD(flags))
//code here
if (IS_RUN_FRNTGRND(flags))
//code here


//Part 2: excute child process

pid = fork()
//fork new process

if (IS_RUN_BCKGRND(flags))
//running background
//code here
if (IS_INPUT_REDIREC(flags))
//input redirection
//code here
if (IS_OUTPUT_REDIREC(flags))
//output redirection
//code here
execvp(cmd, arguments)
//exec the child process
//code here
waipid(pid, &status, 0/WNOHANG);
//wait child or not
//code here

return;
}

\end{verbatim}

\item[3.2.5] \textbf{Error Handling Module}\\

This module reuses the error handling module of apue writing by Richard Stevens.\\
\begin{verbatim}

\end{verbatim}
The function list as follows:\\
void err\_ret(const char *fmt, ...);\\
void err\_sys(const char *fmt, ...);\\
void err\_exit(int error, const char *fmt, ...);\\
void err\_dump(const char *fmt, ...);\\
void err\_msg(const char *fmt, ...);\\
void err\_quit(const char *fmt, ...);\\

\end{description}
\end{itemize}

\item \large \textbf{Requirements Traceability Matrix}\\
\normalsize
\begin{center}
\begin{tabular}{|l|l|}
\hline
\textbf{Requirements} & \textbf{achievements}\\
\hline
quit nomally on special cmd  & exit\\
\hline
Multi-job avariable & fg, \&\\
\hline
input redirection & $<$\\
\hline
output redirection & $>$\\
\hline
%Date & \date{}\\
change prompt & chgpmt *\\
\hline
\end{tabular}
\end{center}

\end{enumerate}
\end{document}
